import { defineStore } from "pinia";
import { ref, computed } from "vue";
import Taro from "@tarojs/taro";
import { getWebSocketUrl, getBackupWebSocketUrl, checkWebSocketConnection } from "@/utils/websocket";
import { useUserStore } from "./user";

/**
 * 聊天消息接口
 */
export interface ChatMessage {
  id: string;
  content: string;
  type: "text" | "image";
  time: string;
  isSelf: boolean;
  senderId: string;
  receiverId: string;
  roomId?: string;
}

/**
 * WebSocket 连接状态
 */
export type ConnectionStatus = "disconnected" | "connecting" | "connected" | "error";

/**
 * WebSocket Store
 * 管理 WebSocket 连接、消息发送和接收
 */
export const useWebSocketStore = defineStore("websocket", () => {
  // WebSocket 实例
  const ws = ref<WebSocket | null>(null);
  
  // 连接状态
  const connectionStatus = ref<ConnectionStatus>("disconnected");
  
  // 连接重试次数
  const retryCount = ref(0);
  
  // 最大重试次数
  const MAX_RETRY_COUNT = 2;
  
  // 重连间隔（毫秒）
  const RETRY_INTERVAL = 3000;
  
  // 心跳间隔（毫秒）
  const HEARTBEAT_INTERVAL = 30000;
  
  // 心跳定时器
  let heartbeatTimer: NodeJS.Timeout | null = null;
  
  // 重连定时器
  let reconnectTimer: NodeJS.Timeout | null = null;
  
  // 聊天消息列表
  const messages = ref<ChatMessage[]>([]);
  
  // 当前聊天室ID
  const currentRoomId = ref<string>("");
  
  // 是否自动重连
  const autoReconnect = ref(true);
  
  // 获取用户 store
  const userStore = useUserStore();
  
  // 计算属性：是否已连接
  const isConnected = computed(() => connectionStatus.value === "connected");
  
  // 计算属性：是否正在连接
  const isConnecting = computed(() => connectionStatus.value === "connecting");
  
  // 计算属性：是否有错误
  const hasError = computed(() => connectionStatus.value === "error");

  /**
   * 获取 WebSocket URL
   * 使用新的配置工具
   */
  const getWebSocketUrlInternal = () => {
    const token = Taro.getStorageSync("token");
    console.log("token", token);
    if (!token) {
      throw new Error("用户未登录，无法建立 WebSocket 连接");
    }
    
    return getWebSocketUrl(token);
  };

  /**
   * 建立 WebSocket 连接
   */
  const connect = async () => {
    try {
      // 如果已经连接或正在连接，直接返回
      if (ws.value && (connectionStatus.value === "connected" || connectionStatus.value === "connecting")) {
        console.log("WebSocket 已连接或正在连接中，跳过重复连接");
        return;
      }
      
      // 如果存在旧的连接，先断开
      if (ws.value) {
        disconnect();
      }
      
      // 启用自动重连
      autoReconnect.value = true;
      
      // 更新连接状态
      connectionStatus.value = "connecting";
      
      // 获取 WebSocket URL
      const wsUrl = getWebSocketUrlInternal();
      
      // 创建 WebSocket 连接
      ws.value = new WebSocket(wsUrl);
      
      // 设置事件监听器
      setupEventListeners();
      
    } catch (error) {
      console.error("WebSocket 连接失败:", error);
      connectionStatus.value = "error";
      handleConnectionError();
    }
  };

  /**
   * 设置 WebSocket 事件监听器
   */
  const setupEventListeners = () => {
    if (!ws.value) return;
    
    // 先清理旧的事件监听器
    ws.value.onopen = null;
    ws.value.onmessage = null;
    ws.value.onclose = null;
    ws.value.onerror = null;
    
    // 连接建立
    ws.value.onopen = () => {
      console.log("WebSocket 连接已建立");
      connectionStatus.value = "connected";
      retryCount.value = 0;
      startHeartbeat();
    };
    
    // 接收消息
    ws.value.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        handleIncomingMessage(data);
      } catch (error) {
        console.error("解析消息失败:", error);
      }
    };
    
    // 连接关闭
    ws.value.onclose = (event) => {
      console.log("WebSocket 连接已关闭:", event.code, event.reason);
      connectionStatus.value = "disconnected";
      stopHeartbeat();
      
      // 如果不是主动断开，尝试重连
      if (autoReconnect.value && event.code !== 1000) {
        handleConnectionError();
      }
    };
    
    // 连接错误
    ws.value.onerror = (error) => {
      console.error("WebSocket 连接错误:", error);
      connectionStatus.value = "error";
      handleConnectionError();
    };
  };

  /**
   * 处理连接错误
   */
  const handleConnectionError = () => {
    if (retryCount.value < MAX_RETRY_COUNT) {
      retryCount.value++;
      console.log(`尝试重连 (${retryCount.value}/${MAX_RETRY_COUNT})...`);
      
      // 第一次重试使用主服务器，第二次重试使用备用服务器
      if (retryCount.value === 1) {
        reconnectTimer = setTimeout(() => {
          connect();
        }, RETRY_INTERVAL);
      } else if (retryCount.value === 2) {
        console.log("尝试使用备用 WebSocket 服务器...");
        connectWithBackup();
      }
    } else {
      console.error("WebSocket 重连失败，已达到最大重试次数");
      // 停止自动重连
      autoReconnect.value = false;
      // 提示用户连接失败
      Taro.showToast({
        title: "连接失败，请检查网络后重试",
        icon: "none",
        duration: 3000
      });
    }
  };

  /**
   * 使用备用服务器连接
   */
  const connectWithBackup = async () => {
    try {
      const token = Taro.getStorageSync("token");
      if (!token) {
        throw new Error("用户未登录，无法建立 WebSocket 连接");
      }

      const backupUrl = getBackupWebSocketUrl(token);
      console.log("尝试连接备用服务器:", backupUrl);
      
      // 检查备用服务器是否可用
      const isAvailable = await checkWebSocketConnection(backupUrl);
      if (!isAvailable) {
        console.log("备用服务器不可用，连接失败");
        // 备用服务器不可用，直接失败
        connectionStatus.value = "error";
        autoReconnect.value = false;
        Taro.showToast({
          title: "连接失败，请检查网络后重试",
          icon: "none",
          duration: 3000
        });
        return;
      }

      // 如果已经连接，先断开
      if (ws.value && connectionStatus.value === "connected") {
        disconnect();
      }
      
      // 更新连接状态
      connectionStatus.value = "connecting";
      
      // 创建 WebSocket 连接
      ws.value = new WebSocket(backupUrl);
      
      // 设置事件监听器
      setupEventListeners();
      
    } catch (error) {
      console.error("备用 WebSocket 连接失败:", error);
      connectionStatus.value = "error";
      // 备用服务器也失败，停止重连
      autoReconnect.value = false;
      Taro.showToast({
        title: "连接失败，请检查网络后重试",
        icon: "none",
        duration: 3000
      });
    }
  };

  /**
   * 断开 WebSocket 连接
   */
  const disconnect = () => {
    console.log("断开 WebSocket 连接");
    
    // 停止自动重连
    autoReconnect.value = false;
    
    // 清除定时器
    stopHeartbeat();
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
    
    // 清理事件监听器
    if (ws.value) {
      ws.value.onopen = null;
      ws.value.onmessage = null;
      ws.value.onclose = null;
      ws.value.onerror = null;
      
      // 关闭连接
      ws.value.close(1000, "主动断开连接");
      ws.value = null;
    }
    
    connectionStatus.value = "disconnected";
    retryCount.value = 0;
    
    // 清空消息列表，避免重连后消息重复
    messages.value = [];
  };

  /**
   * 开始心跳
   */
  const startHeartbeat = () => {
    heartbeatTimer = setInterval(() => {
      if (ws.value && connectionStatus.value === "connected") {
        sendHeartbeat();
      }
    }, HEARTBEAT_INTERVAL);
  };

  /**
   * 停止心跳
   */
  const stopHeartbeat = () => {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer);
      heartbeatTimer = null;
    }
  };

  /**
   * 发送心跳
   */
  const sendHeartbeat = () => {
    // sendMessage({
    //   type: "heartbeat",
    //   content: "ping",
    //   fromUserId: userStore.userInfo.id.toString(),
    //   toUserId: null
    // });
  };

  /**
   * 发送消息
   * @param message 消息对象
   */
  const sendMessage = (message: any) => {
    if (!ws.value || connectionStatus.value !== "connected") {
      console.error("WebSocket 未连接，无法发送消息");
      return false;
    }
    
    try {
      console.log("发送消息:", message);
      ws.value.send(JSON.stringify(message));
      return true;
    } catch (error) {
      console.error("发送消息失败:", error);
      return false;
    }
  };

  /**
   * 发送聊天消息
   * @param content 消息内容
   * @param type 消息类型
   * @param receiverId 接收者ID
   * @param roomId 聊天室ID（可选）
   */
  const sendChatMessage = (content: string, type: "text" | "image", receiverId: string, roomId?: string) => {
    const message = {
      type: type,
      content: content,
      fromUserId: userStore.userInfo.id.toString(),
      toUserId: receiverId
    };
    
    const success = sendMessage(message);
    
    if (success) {
      // 添加到本地消息列表
      const chatMessage: ChatMessage = {
        id: Date.now().toString(),
        content,
        type,
        time: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }),
        isSelf: true,
        senderId: userStore.userInfo.id.toString(),
        receiverId,
        roomId: roomId || currentRoomId.value
      };
      
      messages.value.push(chatMessage);
    }
    
    return success;
  };
  /**
   * 处理接收到的消息
   * @param data 消息数据
   */
  const handleIncomingMessage = (data: any) => {
    console.log("收到消息:", data);
    
    // 处理系统消息（type 为 null 且 fromUserId 为 '系统'）
    if (data.type === null && data.fromUserId === '系统') {
      handleSystemMessage(data);
      return;
    }
    
    // 处理聊天消息
    if (data.type === 'text' || data.type === 'image') {
      handleChatMessage(data);
      return;
    }
    
    // 处理心跳响应
    if (data.type === "heartbeat") {
      return;
    }
    
    console.warn("未知消息类型:", data);
  };

  /**
   * 处理聊天消息
   * @param data 聊天消息数据
   */
  const handleChatMessage = (data: any) => {
    const chatMessage: ChatMessage = {
      id: data.id || Date.now().toString(),
      content: data.content,
      type: data.type || "text",
      time: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }),
      isSelf: data.fromUserId === userStore.userInfo.id.toString(),
      senderId: data.fromUserId,
      receiverId: data.toUserId,
      roomId: data.roomId
    };
    
    messages.value.push(chatMessage);
  };

  /**
   * 处理系统消息
   * @param data 系统消息数据
   */
  const handleSystemMessage = (data: any) => {
    console.log("系统消息:", data);
    
    // 将系统消息也添加到消息列表中，用于显示
    const chatMessage: ChatMessage = {
      id: Date.now().toString(),
      content: data.content,
      type: "text",
      time: new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }),
      isSelf: false,
      senderId: data.fromUserId,
      receiverId: data.toUserId || "",
      roomId: currentRoomId.value
    };
    
    messages.value.push(chatMessage);
    
    // 显示系统通知
    Taro.showToast({
      title: data.content || "收到系统消息",
      icon: "none",
      duration: 2000
    });
  };

  /**
   * 加入聊天室
   * @param roomId 聊天室ID
   */
  const joinRoom = (roomId: string) => {
    currentRoomId.value = roomId;
    
    const message = {
      type: "join_room",
      content: roomId,
      fromUserId: userStore.userInfo.id.toString(),
      toUserId: null
    };
    
    sendMessage(message);
  };

  /**
   * 离开聊天室
   */
  const leaveRoom = () => {
    if (currentRoomId.value) {
      const message = {
        type: "leave_room",
        content: currentRoomId.value,
        fromUserId: userStore.userInfo.id.toString(),
        toUserId: null
      };
      
      sendMessage(message);
      currentRoomId.value = "";
    }
  };

  /**
   * 清空消息列表
   */
  const clearMessages = () => {
    messages.value = [];
  };

  /**
   * 获取指定聊天室的消息
   * @param roomId 聊天室ID
   */
  const getRoomMessages = (roomId: string) => {
    return messages.value.filter(msg => msg.roomId === roomId);
  };

  /**
   * 获取与指定用户的消息
   * @param userId 用户ID
   */
  const getUserMessages = (userId: string) => {
    return messages.value.filter(msg => 
      msg.senderId === userId || msg.receiverId === userId
    );
  };

  return {
    // 状态
    connectionStatus,
    isConnected,
    isConnecting,
    hasError,
    messages,
    currentRoomId,
    retryCount,
    
    // 方法
    connect,
    disconnect,
    sendMessage,
    sendChatMessage,
    joinRoom,
    leaveRoom,
    clearMessages,
    getRoomMessages,
    getUserMessages
  };
});
